#include <iostream>
#include <string>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

std::string rsa_encrypt(const std::string &plaintext, RSA *public_key) {
    int rsa_size = RSA_size(public_key);
    unsigned char *encrypted = new unsigned char[rsa_size];

    // 使用RSA公钥加密
    int result = RSA_public_encrypt(plaintext.size(), (unsigned char*)plaintext.c_str(),
                                    encrypted, public_key, RSA_PKCS1_PADDING);
    if (result == -1) {
        ERR_print_errors_fp(stderr);
        delete[] encrypted;
        return "";
    }

    std::string ciphertext(reinterpret_cast<char*>(encrypted), result);
    delete[] encrypted;
    return ciphertext;
}

std::string rsa_decrypt(const std::string &ciphertext, RSA *private_key) {
    int rsa_size = RSA_size(private_key);
    unsigned char *decrypted = new unsigned char[rsa_size];
    
    // 使用RSA私钥解密
    int result = RSA_private_decrypt(ciphertext.size(), (unsigned char*)ciphertext.c_str(),
                                      decrypted, private_key, RSA_PKCS1_PADDING);
    if (result == -1) {
        ERR_print_errors_fp(stderr);
        delete[] decrypted;
        return "";
    }

    std::string plaintext(reinterpret_cast<char*>(decrypted), result);
    delete[] decrypted;
    return plaintext;
}

void generate_keys(RSA **public_key, RSA **private_key) {
    *private_key = RSA_generate_key(2048, RSA_F4, nullptr, nullptr);
    BIO *pub = BIO_new(BIO_s_mem());
    PEM_write_bio_RSA_PUBKEY(pub, *private_key);
    *public_key = PEM_read_bio_RSA_PUBKEY(pub, nullptr, nullptr, nullptr);
    BIO_free(pub);
}

int main() {
    RSA *public_key = nullptr;
    RSA *private_key = nullptr;

    // 生成RSA密钥对
    generate_keys(&public_key, &private_key);

    std::string message = "202111672313LanTian";
    std::cout << "Original Message: " << message << std::endl;

    // 加密
    std::string encrypted_message = rsa_encrypt(message, public_key);
    std::cout << "Encrypted Message: " << encrypted_message << std::endl;

    // 解密
    std::string decrypted_message = rsa_decrypt(encrypted_message, private_key);
    std::cout << "Decrypted Message: " << decrypted_message << std::endl;

    // 清理资源
    RSA_free(public_key);
    RSA_free(private_key);

    return 0;
}

#include <iostream>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <iomanip>
#include <sstream>
#include <string.h>
#include <vector>

void printHex(const unsigned char* buf, size_t len) {
    for (size_t i = 0; i < len; i++)
        std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)buf[i];
    std::cout << std::dec << std::endl;
}

std::string aes_encrypt(const std::string& plaintext, const unsigned char* key, unsigned char* iv) {
    AES_KEY enc_key;
    AES_set_encrypt_key(key, 128, &enc_key);

    // 填充
    std::string padded_plaintext = plaintext;
    int padding = AES_BLOCK_SIZE - (padded_plaintext.size() % AES_BLOCK_SIZE);
    padded_plaintext.append(padding, padding);

    std::vector<unsigned char> ciphertext(padded_plaintext.size());
    AES_cbc_encrypt(reinterpret_cast<const unsigned char*>(padded_plaintext.c_str()),
                    ciphertext.data(),
                    padded_plaintext.size(),
                    &enc_key,
                    iv,
                    AES_ENCRYPT);

    return std::string(reinterpret_cast<char*>(ciphertext.data()), ciphertext.size());
}

std::string aes_decrypt(const std::string& ciphertext, const unsigned char* key, unsigned char* iv) {
    AES_KEY dec_key;
    AES_set_decrypt_key(key, 128, &dec_key);

    std::vector<unsigned char> decrypted(ciphertext.size());
    AES_cbc_encrypt(reinterpret_cast<const unsigned char*>(ciphertext.c_str()),
                    decrypted.data(),
                    ciphertext.size(),
                    &dec_key,
                    iv,
                    AES_DECRYPT);

    // 去除填充
    int padding = decrypted.back();
    decrypted.resize(decrypted.size() - padding);
    
    return std::string(reinterpret_cast<char*>(decrypted.data()), decrypted.size());
}

int main() {
    const std::string plaintext = "202111672313LanTian";
    unsigned char key[AES_BLOCK_SIZE]; // 128 bits
    unsigned char iv[AES_BLOCK_SIZE]; // Initialization vector

    // 随机生成密钥和 IV
    RAND_bytes(key, sizeof(key));
    RAND_bytes(iv, sizeof(iv));

    std::cout << "Key: ";
    printHex(key, sizeof(key));
    std::cout << "IV: ";
    printHex(iv, sizeof(iv));

    std::string ciphertext = aes_encrypt(plaintext, key, iv);
    std::cout << "Ciphertext: ";
    printHex(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.size());

    std::string decrypted_text = aes_decrypt(ciphertext, key, iv);
    std::cout << "Decrypted Text: " << decrypted_text << std::endl;

    return 0;
}
